//
//  CIMKeychain.m
//  CIMSDK_iOS
//
//  Created by Chentao on 2022/9/20.
//

#import "CIMKeychain.h"

NSString *const KEY_APP_CONFIG = @"com.cim";

@implementation CIMKeychain

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    NSMutableDictionary *info = [[NSMutableDictionary alloc] init];

    [info setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    [info setObject:service forKey:(id)kSecAttrService];
    [info setObject:service forKey:(id)kSecAttrAccount];
    [info setObject:(id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
    return info;
}

+ (void)saveValue:(id)value key:(NSString *)key {
    NSMutableDictionary *configMap = [CIMKeychain load:KEY_APP_CONFIG];

    if (!configMap) {
        configMap = [[NSMutableDictionary alloc] init];
    }

    [configMap setValue:value forKey:key];
    [CIMKeychain save:KEY_APP_CONFIG data:configMap];
}

+ (void)save:(NSString *)service data:(id)data {
    // Get search dictionary
    NSMutableDictionary *keychainQuery = [CIMKeychain getKeychainQuery:service];

    // Delete old item before add new item
    SecItemDelete((CFDictionaryRef)keychainQuery);
    // Add new object to search dictionary(Attention:the data format)
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
    // Add item to keychain with the search dictionary
    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}

+ (id)getValueForKey:(NSString *)key {
    NSMutableDictionary *configMap = (NSMutableDictionary *)[CIMKeychain load:KEY_APP_CONFIG];

    return [configMap objectForKey:key];
}

+ (id)load:(NSString *)service {
    id ret = nil;
    NSMutableDictionary *keychainQuery = [CIMKeychain getKeychainQuery:service];

    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    CFDataRef keyData = NULL;

    if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
        } @catch (NSException *e) {
            NSLog(@"Unarchive of %@ failed: %@", service, e);
        } @finally {
        }
    }

    if (keyData) {
        CFRelease(keyData);
    }

    return ret;
}

+ (void)deleteValueForKey:(NSString *)key {
    NSMutableDictionary *configMap = (NSMutableDictionary *)[CIMKeychain load:KEY_APP_CONFIG];

    [configMap removeObjectForKey:key];
    [CIMKeychain save:KEY_APP_CONFIG data:configMap];
}

+ (void)clearAllConfig {
    NSMutableDictionary *keychainQuery = [CIMKeychain getKeychainQuery:KEY_APP_CONFIG];

    SecItemDelete((CFDictionaryRef)keychainQuery);
}

@end
